package servicex

import (
	"errors"
	"regexp"
	"strings"
	"time"

	"github.com/sleagon/chinaid"
	"zhonghui/console/warehouse/helperx"

	"zhonghui/console/warehouse/structx"
)

// ParseIdCard 解析身份证 处理掩码 性别 生日 年龄
//
// 年龄部分
// age：周岁年龄
// age_t(1)：生日加1天的年龄，比周岁小，用于特殊场景，自行选择
// age_st(1)：生日减1天的年龄，比周岁大，用于特殊场景，自行选择
//
// 如：今天是2021年1月3日
// 生日是2020年1月1日，则输出：除了T3，其余都是1岁
// 生日是2020年1月6日，则输出：除了ST3，其余都是0岁
func ParseIdCard(no string) (*structx.IdCard, error) {
	no = strings.TrimSpace(no)
	no = strings.ToUpper(no)

	id := chinaid.IDCard(no)
	res, err := id.Decode()
	if err != nil {
		return nil, errors.New("身份证号不合法")
	}

	idCard := structx.IdCard{}
	idCard.IdCard = no
	idCard.Mask = idCard.IdCard[:2] + "************" + idCard.IdCard[14:]
	idCard.Gender = "f"
	if res.Sex == 1 {
		idCard.Gender = "m"
	}

	idCard.BirthDay = res.Birthday.Format("2006-01-02")

	// 年龄
	idCard.Age = helperx.GetAgeFromBirthday(res.Birthday)
	idCard.AgeT1 = helperx.GetAgeFromBirthday(res.Birthday.Add(24 * time.Hour))
	idCard.AgeT2 = helperx.GetAgeFromBirthday(res.Birthday.Add(48 * time.Hour))
	idCard.AgeT3 = helperx.GetAgeFromBirthday(res.Birthday.Add(72 * time.Hour))
	idCard.AgeST1 = helperx.GetAgeFromBirthday(res.Birthday.Add(-24 * time.Hour))
	idCard.AgeST2 = helperx.GetAgeFromBirthday(res.Birthday.Add(-48 * time.Hour))
	idCard.AgeST3 = helperx.GetAgeFromBirthday(res.Birthday.Add(-72 * time.Hour))

	return &idCard, nil
}

// ParseRealName 解析姓名 处理掩码
func ParseRealName(name string) (*structx.RealName, error) {
	name = strings.TrimSpace(name)
	// 兼容少数民族姓名各种点点
	dots := []string{"。", ".", "•", "-", ",", " "}
	for _, dot := range dots {
		name = strings.Replace(name, dot, "·", -1)
	}

	if !regexp.MustCompile("^\\p{Han}+(\u00B7\\p{Han}+)*?$").MatchString(name) {
		return nil, errors.New("姓名必须全部是中文")
	}

	nameRune := []rune(name)
	hanLen := len(nameRune)
	if hanLen < 2 {
		return nil, errors.New("姓名至少为2个汉字")
	}

	realName := structx.RealName{}
	realName.Name = name
	realName.Mask = string(nameRune[0]) + "*"
	if hanLen > 2 {
		realName.Mask = string(nameRune[0]) + strings.Repeat("*", hanLen-2) + string(nameRune[hanLen-1])
	}

	return &realName, nil
}

// ParseBankAccount 解析银行储蓄卡号
func ParseBankAccount(account string) (*structx.BankAccount, error) {
	account = strings.TrimSpace(account)
	// 12-19位数字，第一位不能是0
	if !regexp.MustCompile("^([1-9]{1})(\\d{11}|\\d{15}|\\d{16}|\\d{17}|\\d{18})$").MatchString(account) {
		return nil, errors.New("银行卡格式不正确")
	}

	bankAccount := structx.BankAccount{}
	bankAccount.BankAccount = account
	bankAccount.Mask = account[:6] + strings.Repeat("*", len(account)-10) + account[len(account)-4:]

	return &bankAccount, nil
}

// ParseOtherCard 解析其他证件号
func ParseOtherCard(no string) (*structx.OtherCard, error) {
	no = strings.TrimSpace(no)
	reg, _ := regexp.Compile(`^[A-Za-z0-9_.]+$`)
	if len(reg.FindAllString(no, -1)) != 1 {
		return nil, errors.New("证件号只能为大小写英文和数字的组合")
	}

	// 判断长度，处理掩码
	var mask string
	noRune := []rune(no)
	hanLen := len(noRune)

	switch len(no) {
	case 1:
		mask = no
	case 2:
		mask = no[:1] + "*"
	case 3, 4, 5:
		mask = string(noRune[0]) + strings.Repeat("*", hanLen-2) + string(noRune[hanLen-1])
	default:
		mask = string(noRune[0]) + string(noRune[1]) + strings.Repeat("*", hanLen-4) + string(noRune[hanLen-2]) + string(noRune[hanLen-1])
	}

	return &structx.OtherCard{
		Card: no,
		Mask: mask,
	}, nil
}
